package com.lhd.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import cn.hutool.core.util.StrUtil;
import com.lhd.component.RedisComponent;
import com.lhd.entity.constants.Constants;
import com.lhd.entity.dto.AdditionInfoDto;
import com.lhd.entity.dto.PostActivityDto;
import com.lhd.entity.enums.*;
import com.lhd.entity.po.Record;
import com.lhd.entity.po.User;
import com.lhd.entity.po.UserSysClass;
import com.lhd.entity.query.*;
import com.lhd.mappers.RecordMapper;
import com.lhd.mappers.UserMapper;
import com.lhd.mappers.UserSysClassMapper;
import org.springframework.stereotype.Service;

import com.lhd.entity.po.Activity;
import com.lhd.entity.vo.PaginationResultVO;
import com.lhd.mappers.ActivityMapper;
import com.lhd.service.ActivityService;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Author: liuhd
 * @Date: 2025/03/16
 * @Description: Activity业务接口实现类
 */
@Service
public class ActivityServiceImpl implements ActivityService {
    @Resource
    private ActivityMapper<Activity, ActivityQuery> activityMapper;
    @Resource
    private UserMapper<User, UserQuery> userMapper;
    @Resource
    private RecordMapper<Record, RecordQuery> recordMapper;
    @Resource
    private RedisComponent redisComponent;
    @Resource
    private UserSysClassMapper<UserSysClass, UserSysClassQuery> userSysClassMapper;

    /**
     * 根据条件查询列表
     */
    @Override
    public List<Activity> findListByQuery(ActivityQuery query) {
        return activityMapper.selectList(query);
    }

    /**
     * 根据条件查询数量
     */
    @Override
    public Long findCountByQuery(ActivityQuery query) {
        return activityMapper.selectCount(query);
    }

    /**
     * 分页查询
     */
    @Override
    public PaginationResultVO<Activity> findListByPage(ActivityQuery query) {
        // 查出查询的结果数量
        long count = findCountByQuery(query);
        // 如果没给pageSize 默认是15
        long pageSize = query.getPageSize() == null ? PageSize.SIZE15.getSize() : query.getPageSize();
        // 构建SimplePage 可以确定limit的index与offset以及总页数 以及真正的pageNo
        SimplePage page = new SimplePage(query.getPageNo(), count, pageSize);
        // 设置到query中 xml中会使用query.simplePage.start与query.simplePage.end
        query.setSimplePage(page);
        // 用query查询 此时是分页条件查询
        List<Activity> list = this.findListByQuery(query);
        // 将结果塞到PaginationResultVO中
        PaginationResultVO<Activity> result = new PaginationResultVO<>(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
        return result;
    }

    /**
     * 新增
     */
    @Override
    public Long add(Activity bean) {
        return activityMapper.insert(bean);
    }

    /**
     * 新增或更新
     */
    @Override
    public Long addOrUpdate(Activity bean) {
        return activityMapper.insertOrUpdate(bean);
    }

    /**
     * 批量新增
     */
    @Override
    public Long addBatch(List<Activity> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0L;
        }
        return activityMapper.insertBatch(listBean);
    }

    /**
     * 批量新增或更新
     */
    @Override
    public Long addOrUpdateBatch(List<Activity> listBean) {
        if (listBean == null || listBean.isEmpty()) {
            return 0L;
        }
        return activityMapper.insertOrUpdateBatch(listBean);
    }

    /**
     * 多条件更新
     */
    @Override
    public Long updateByQuery(Activity bean, ActivityQuery query) {
        return activityMapper.updateByQuery(bean, query);
    }

    /**
     * 多条件删除
     */
    @Override
    public Long deleteByQuery(ActivityQuery query) {
        return activityMapper.deleteByQuery(query);
    }

    /**
     * 根据PRIMARY查询
     */
    @Override
    public Activity getActivityById(Integer id) {
        return activityMapper.selectById(id);
    }

    /**
     * 根据PRIMARY删除
     */
    @Override
    public Long deleteActivityById(Integer id) {
        return activityMapper.deleteById(id);
    }

    /**
     * 根据PRIMARY更新
     */
    @Override
    public Long updateActivityById(Activity bean, Integer id) {
        return activityMapper.updateById(bean, id);
    }

    @Override
    @Transactional
    public List<Activity> postActivity(PostActivityDto postActivityDto, Integer uid, String type) {
        List<Integer> sidList = postActivityDto.getSidList();
        Integer cid = postActivityDto.getCid();
        String title = postActivityDto.getTitle();
        Integer lastTime = postActivityDto.getLastTime();
        Integer lateTime = postActivityDto.getLateTime();
        AdditionInfoDto additionInfo = postActivityDto.getAdditionInfo();
        Integer isVerify = postActivityDto.getIsVerify();
        // 插入活动记录,多班级发布的活动id不一样,其他活动内容都一样
        List<Activity> activityList = new ArrayList<>();
        for (Integer sid : sidList) {
            Activity activity = new Activity();
            activity.setUid(uid);
            activity.setType(type);
            activity.setCid(cid);
            activity.setTitle(title);
            activity.setSid(sid);
            activity.setLastTime(lastTime);
            activity.setLateTime(lateTime);
            activity.setIsVerify(isVerify);

            Date createTime = new Date();
            activity.setCreateTime(createTime);
            // 计算结束时间
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(createTime);
            calendar.add(Calendar.MINUTE, lastTime); // 加上持续时间（分钟）
            Date endTime = calendar.getTime();

            activity.setEndTime(endTime); // 设置结束时间

            activityMapper.insert(activity);

            activityList.add(activity);
        }

        // 将涉及到班级所有学生插入record表中
        // 1.查出各班级所有的学生
        UserSysClassQuery userSysClassQuery = new UserSysClassQuery();
        userSysClassQuery.setSidList(sidList);
        userSysClassQuery.setRole(RoleEnum.STUDENT.getCode());
        // 联表查询
        List<UserSysClass> studentList = userSysClassMapper.selectStudentIdList(userSysClassQuery);

        // 使用Stream API进行转换
        Map<Integer, List<Integer>> studentMap = studentList.stream()
                .collect(Collectors.groupingBy(
                        UserSysClass::getSid, // 按sid分组
                        Collectors.mapping(UserSysClass::getUid, Collectors.toList()) // 将每个UserSysClass对象映射为其uid，并收集到列表中
                ));

        // 构造aid:studentList的Map
        Map<Integer, List<Integer>> aid_studentList_map = new HashMap<>();
        for (Activity activity : activityList) {
            Integer aid = activity.getId();
            Integer sid = activity.getSid();
            // 拿到各个班级内的学生id
            List<Integer> list = studentMap.get(sid);

            aid_studentList_map.put(aid, list);

        }
        // 2.插入record
        List<Record> recordlist = new ArrayList<>();

        for (Map.Entry<Integer, List<Integer>> entry : aid_studentList_map.entrySet()) {
            Integer aid = entry.getKey();
            List<Integer> list = entry.getValue();
            // 如果班级里面没有学生
            if (list == null || list.isEmpty()) {
                continue;
            }
            for (Integer id : list) {
                Record record = new Record();
                record.setAid(aid);
                record.setStatus(RecordStatusEnum.TODO_LEAVE.getCode());
                record.setStuId(id);
                recordlist.add(record);
            }
        }

        recordMapper.insertBatch(recordlist);


		String redisKey = getRedisKey(type);

		// 保存信息到redis
		if (redisKey != null){
			for (Activity activity : activityList) {
				Integer aid = activity.getId();
				redisComponent.saveAdditionInfo(additionInfo, aid, lastTime,redisKey);
			}
		}


        return activityList;
    }

	/**
	 * @description: 确定redisKey
	 * @param type
	 * @return java.lang.String
	 * @author liuhd
	 * 2025/3/24 14:53
	 */
	private static String getRedisKey(String type) {
		String redisKey = null;
		if (ActivityTypeRedisKeyEnum.GESTURE_CHECK_IN.getType().equals(type)){
			redisKey = ActivityTypeRedisKeyEnum.GESTURE_CHECK_IN.getRedisKey();
		}
		if (ActivityTypeRedisKeyEnum.LOCATION_CHECK_IN.getType().equals(type)){
			redisKey = ActivityTypeRedisKeyEnum.LOCATION_CHECK_IN.getRedisKey();
		}
		if (ActivityTypeRedisKeyEnum.QR_CODE_CHECK_IN.getType().equals(type)){
			redisKey = ActivityTypeRedisKeyEnum.QR_CODE_CHECK_IN.getRedisKey();
		}
		if (ActivityTypeRedisKeyEnum.CODE_CHECK_IN.getType().equals(type)){
			redisKey = ActivityTypeRedisKeyEnum.CODE_CHECK_IN.getRedisKey();
		}
		return redisKey;
	}


    /**
     * @description: 停止活动
     * @param aid
     * @return
     * @author liuhd
     * 2025/5/9 21:24
     */
    @Override
    @Transactional
    public void quit(Integer aid) {
        RecordQuery recordQuery = new RecordQuery();
        recordQuery.setAid(aid);
        recordQuery.setStatus(RecordStatusEnum.TODO_LEAVE.getCode());
        Record record = new Record();
        record.setStatus(RecordStatusEnum.ABSENT.getCode());
        recordMapper.updateByQuery(record,recordQuery);

        Activity activity = new Activity();
        activity.setEndTime(new Date());
        activityMapper.updateById(activity,aid);
    }
}